package com.code2roc.xhood.asm;

import com.code2roc.xhood.util.CommonUtil;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

import java.util.LinkedHashMap;

public class ClassAnnotationAdapter extends AnnotationVisitor {
    private LinkedHashMap<String, String> modifyMap;

    public ClassAnnotationAdapter(AnnotationVisitor annotationVisitor, LinkedHashMap<String, String> modifyMap) {
        super(Opcodes.ASM9);
        av = annotationVisitor;
        this.modifyMap = modifyMap;
    }

    @Override
    public void visit(String name, Object value) {
        if (value != null && value instanceof Type) {
            Type type = (Type) value;
            String descriptor = type.getDescriptor();
            if (descriptor != null) {
                for (String key : modifyMap.keySet()) {
                    descriptor = CommonUtil.replace(descriptor, key, modifyMap.get(key));
                }
            }
            value = Type.getType(descriptor);
        }
        if (value != null && value instanceof String) {
            String content = String.valueOf(value);
            if (content.contains("@annotation") || content.contains("@within")) {
                for (String key : modifyMap.keySet()) {
                    String convertKey = key.replace("/", ".");
                    String convertValue = modifyMap.get(key).replace("/", ".");
                    content = CommonUtil.replace(content, convertKey, convertValue);
                }
            }
            value = content;
        }
        super.visit(name, value);
    }

    @Override
    public AnnotationVisitor visitArray(String name) {
        AnnotationVisitor annotationVisitor = super.visitArray(name);
        return new ClassAnnotationAdapter(annotationVisitor, modifyMap);
    }

    @Override
    public void visitEnum(String name, String descriptor, String value) {
        if (descriptor != null) {
            for (String key : modifyMap.keySet()) {
                descriptor = CommonUtil.replace(descriptor, key, modifyMap.get(key));
            }
        }
        super.visitEnum(name, descriptor, value);
    }

    @Override
    public AnnotationVisitor visitAnnotation(String name, String descriptor) {
        if (descriptor != null) {
            for (String key : modifyMap.keySet()) {
                descriptor = CommonUtil.replace(descriptor, key, modifyMap.get(key));
            }
        }
        AnnotationVisitor annotationVisitor = super.visitAnnotation(name, descriptor);
        return new ClassAnnotationAdapter(annotationVisitor, modifyMap);
    }
}
